/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package MonkeyStuff;

import B3D_Elements.B3D_Lights.B3D_AmbientLight;
import B3D_Elements.B3D_Lights.B3D_DirectionalLight;
import B3D_Elements.B3D_Lights.B3D_PointLight;
import B3D_Elements.B3D_Lights.B3D_SpotLight;
import B3D_Elements.B3D_Spatials.B3D_Geometrys.B3D_Box;
import B3D_Elements.B3D_Spatials.B3D_Geometrys.B3D_Cylinder;
import B3D_Elements.B3D_Spatials.B3D_Geometrys.B3D_ParticleEffect;
import B3D_Elements.B3D_Spatials.B3D_Geometrys.B3D_MultipleTextureSkyBox;
import B3D_Elements.B3D_Spatials.B3D_Geometrys.B3D_SingleTextureSkyBox;
import B3D_Elements.B3D_Spatials.B3D_Geometrys.B3D_Sphere;
import B3D_Elements.B3D_Spatials.B3D_Geometrys.B3D_Torus;
import B3D_Elements.B3D_Spatials.B3D_Model;
import B3D_Elements.B3D_Spatials.B3D_Node;
import B3D_Elements.B3D_Spatials.B3D_Spatial;
import B3D_Elements.Others.B3D_Material;
import B3D_Elements.Others.B3D_MaterialPropertyList;
import General.CurrentData;
import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.light.Light;
import com.jme3.light.PointLight;
import com.jme3.light.SpotLight;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Cylinder;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Torus;
import com.simsilica.lemur.geom.MBox;
import java.util.UUID;

/**
 *
 * @author David
 */
public class SceneNode extends Node
{

    public SceneNode()
    {
        setName("Scene");
    }

    /**
     *
     * @param spatial
     * @return
     */
    @Override
    public int detachChild(Spatial spatial)
    {
        CurrentData.getEditorWindow().getB3DApplication().getElementList().removeByObject(spatial);
        super.detachChild(spatial);
        Spatial empty = null;
        CurrentData.getEditorWindow().getB3DApplication().setSelectedElement(empty);
        CurrentData.getEditorWindow().getB3DApplication().setSyncTree(true);
        return children.size();
    }

    @Override
    public void removeLight(Light light)
    {
        for (LightModel lm : CurrentData.getEditorWindow().getB3DApplication().getLightModels())
        {
            if (light.equals(lm.getLight()))
            {
                CurrentData.getEditorWindow().getB3DApplication().getLightModels().remove(lm);
                CurrentData.getEditorWindow().getB3DApplication().getEditorNode().detachChild(lm.getNode());
                break;
            }
        }
        CurrentData.getEditorWindow().getB3DApplication().getElementList().removeByObject(light);
        super.removeLight(light);
        Spatial empty = null;
        CurrentData.getEditorWindow().getB3DApplication().setSelectedElement(empty);
        CurrentData.getEditorWindow().getB3DApplication().setSyncTree(true);
    }

    @Override
    public void addLight(Light light)
    {
        if (light instanceof AmbientLight)
        {
            AmbientLight tempLight = (AmbientLight) light;
            B3D_AmbientLight b3D_AmbientLight = new B3D_AmbientLight(tempLight.getName(), tempLight.getColor());
            CurrentData.getEditorWindow().getB3DApplication().getElementList().putByObject(tempLight, b3D_AmbientLight);
        } else if (light instanceof DirectionalLight)
        {
            DirectionalLight tempLight = (DirectionalLight) light;
            B3D_DirectionalLight b3D_DirectionalLight = new B3D_DirectionalLight(tempLight.getName(), tempLight.getColor(), tempLight.getDirection());
            CurrentData.getEditorWindow().getB3DApplication().getElementList().putByObject(tempLight, b3D_DirectionalLight);
        } else if (light instanceof PointLight)
        {
            PointLight tempLight = (PointLight) light;
            B3D_PointLight b3D_PointLight = new B3D_PointLight(tempLight.getName(), tempLight.getColor(), tempLight.getPosition(), tempLight.getRadius());
            CurrentData.getEditorWindow().getB3DApplication().getElementList().putByObject(tempLight, b3D_PointLight);
        } else if (light instanceof SpotLight)
        {
            SpotLight tempLight = (SpotLight) light;
            B3D_SpotLight b3D_SpotLight = new B3D_SpotLight(
                    tempLight.getName(),
                    tempLight.getColor(),
                    tempLight.getPosition(),
                    tempLight.getDirection(),
                    tempLight.getSpotInnerAngle(),
                    tempLight.getSpotOuterAngle(),
                    tempLight.getSpotRange());
            CurrentData.getEditorWindow().getB3DApplication().getElementList().putByObject(tempLight, b3D_SpotLight);
        }
        LightModel newLightModel = new LightModel(light);
        CurrentData.getEditorWindow().getB3DApplication().getLightModels().add(newLightModel);
        CurrentData.getEditorWindow().getB3DApplication().setSyncTree(true);
        super.addLight(light);
    }

    /**
     *
     * @param spatial
     * @return
     */
    @Override
    public int attachChild(Spatial spatial)
    {
        register(spatial, null);
        return children.size();
    }

    private void register(Spatial spatial, Node parent)
    {
        B3D_Spatial b3D_Spatial = null;
        if (spatial instanceof Geometry)
        {
            Geometry tempGeometry = (Geometry) spatial;
            tempGeometry.getMaterial().getAdditionalRenderState().setWireframe(CurrentData.getConfiguration().getSettings().get("showwire").equals("true"));
            if (spatial instanceof ParticleEmitter)
            {
                ParticleEmitter tempParticleEmitter = (ParticleEmitter) tempGeometry;
                B3D_ParticleEffect b3D_ParticleEffect = null;
                B3D_ParticleEffect.Type type;
                if (tempParticleEmitter.getShape().equals(ParticleMesh.Type.Point))
                {
                    type = B3D_ParticleEffect.Type.Triangle;
                } else
                {
                    type = B3D_ParticleEffect.Type.Point;
                }
                b3D_ParticleEffect = new B3D_ParticleEffect(
                        tempParticleEmitter.getName(),
                        tempParticleEmitter.getMaterial().getParam("Texture").toString(),
                        tempParticleEmitter.getGravity(),
                        tempParticleEmitter.getParticleInfluencer().getInitialVelocity(),
                        tempParticleEmitter.getStartSize(),
                        tempParticleEmitter.getEndSize(),
                        tempParticleEmitter.getStartColor(),
                        tempParticleEmitter.getEndColor(),
                        tempParticleEmitter.getParticleInfluencer().getVelocityVariation(),
                        tempParticleEmitter.getHighLife(),
                        tempParticleEmitter.getLowLife(),
                        tempParticleEmitter.getRotateSpeed(),
                        tempParticleEmitter.getParticlesPerSec(),
                        tempParticleEmitter.getImagesX(),
                        tempParticleEmitter.getImagesY(),
                        tempParticleEmitter.getMaxNumParticles(),
                        tempParticleEmitter.getMaterial().getAdditionalRenderState().isDepthWrite(),
                        type);
                spatial.setUserData("ID", b3D_ParticleEffect.getID().toString());
                b3D_Spatial = b3D_ParticleEffect;
                CurrentData.getEditorWindow().getB3DApplication().getElementList().putByObject(
                        tempGeometry, b3D_ParticleEffect);
            } else
            {
                if (tempGeometry.getMesh() instanceof MBox)
                {
                    int xSlices = (Integer) tempGeometry.getUserData("xSlices");
                    int ySlices = (Integer) tempGeometry.getUserData("ySlices");
                    int zSlices = (Integer) tempGeometry.getUserData("zSlices");
                    B3D_Box b3D_Box = new B3D_Box(
                            tempGeometry.getName(),
                            new B3D_Material(tempGeometry.getMaterial().getMaterialDef().getAssetName(), new B3D_MaterialPropertyList()),
                            xSlices, ySlices, zSlices);
                    spatial.setUserData("ID", b3D_Box.getID().toString());
                    b3D_Spatial = b3D_Box;
                    CurrentData.getEditorWindow().getB3DApplication().getElementList().putByObject(
                            tempGeometry, b3D_Box);
                } else if (tempGeometry.getMesh() instanceof Cylinder)
                {
                    Cylinder tempCylinder = (Cylinder) tempGeometry.getMesh();
                    B3D_Cylinder b3D_Cylinder = new B3D_Cylinder(tempGeometry.getName(),
                            new B3D_Material(tempGeometry.getMaterial().getMaterialDef().getAssetName(), new B3D_MaterialPropertyList()),
                            tempCylinder.getAxisSamples(),
                            tempCylinder.getRadialSamples(),
                            tempCylinder.getRadius(),
                            tempCylinder.getRadius2(),
                            tempCylinder.getHeight(),
                            tempCylinder.isClosed(),
                            tempCylinder.isInverted());
                    spatial.setUserData("ID", b3D_Cylinder.getID().toString());
                    b3D_Spatial = b3D_Cylinder;
                    CurrentData.getEditorWindow().getB3DApplication().getElementList().putByObject(
                            tempGeometry,
                            b3D_Cylinder);
                } else if (tempGeometry.getMesh() instanceof Sphere)
                {
                    Sphere tempSphere = (Sphere) tempGeometry.getMesh();
                    if (tempGeometry.getUserData("north") != null)
                    {
                        if (tempGeometry.getUserData("south") != null)
                        {
                            B3D_MultipleTextureSkyBox b3D_MSkyBox = new B3D_MultipleTextureSkyBox(tempGeometry.getName(),
                                    tempGeometry.getUserData("north").toString(),
                                    tempGeometry.getUserData("south").toString(),
                                    tempGeometry.getUserData("west").toString(),
                                    tempGeometry.getUserData("east").toString(),
                                    tempGeometry.getUserData("top").toString(),
                                    tempGeometry.getUserData("bottom").toString());
                            spatial.setUserData("ID", b3D_MSkyBox.getID().toString());
                            b3D_Spatial = b3D_MSkyBox;
                            CurrentData.getEditorWindow().getB3DApplication().getElementList().putByObject(
                                    tempGeometry,
                                    b3D_MSkyBox);
                        } else
                        {
                            B3D_SingleTextureSkyBox b3D_SSkyBox = new B3D_SingleTextureSkyBox(tempGeometry.getName(), tempGeometry.getUserData("north").toString());
                            spatial.setUserData("ID", b3D_SSkyBox.getID().toString());
                            b3D_Spatial = b3D_SSkyBox;
                            CurrentData.getEditorWindow().getB3DApplication().getElementList().putByObject(
                                    tempGeometry,
                                    b3D_SSkyBox);
                        }
                    } else
                    {
                        B3D_Sphere b3D_Sphere = new B3D_Sphere(tempGeometry.getName(),
                                new B3D_Material(tempGeometry.getMaterial().getMaterialDef().getAssetName(), new B3D_MaterialPropertyList()),
                                tempSphere.getRadialSamples(),
                                tempSphere.getZSamples(),
                                tempSphere.getRadius());
                        spatial.setUserData("ID", b3D_Sphere.getID().toString());
                        b3D_Spatial = b3D_Sphere;
                        CurrentData.getEditorWindow().getB3DApplication().getElementList().putByObject(
                                tempGeometry,
                                b3D_Sphere);
                    }
                } else if (tempGeometry.getMesh() instanceof Torus)
                {
                    Torus tempTorus = (Torus) tempGeometry.getMesh();
                    B3D_Torus b3D_Torus = new B3D_Torus(tempGeometry.getName(),
                            new B3D_Material(tempGeometry.getMaterial().getMaterialDef().getAssetName(), new B3D_MaterialPropertyList()),
                            tempTorus.getCircleSamples(),
                            tempTorus.getRadialSamples(),
                            tempTorus.getInnerRadius(),
                            tempTorus.getOuterRadius());
                    spatial.setUserData("ID", b3D_Torus.getID().toString());
                    b3D_Spatial = b3D_Torus;
                    CurrentData.getEditorWindow().getB3DApplication().getElementList().putByObject(
                            tempGeometry,
                            b3D_Torus);
                } else
                {
                    B3D_Model b3D_Model = new B3D_Model(tempGeometry.getName(), tempGeometry.getUserData("modelName").toString(), new B3D_Material(tempGeometry.getMaterial().getMaterialDef().getAssetName(), new B3D_MaterialPropertyList()));
                    spatial.setUserData("ID", b3D_Model.getID().toString());
                    b3D_Spatial = b3D_Model;
                    CurrentData.getEditorWindow().getB3DApplication().getElementList().putByObject(
                            tempGeometry, b3D_Model);
                }
            }
        } else if (spatial instanceof Node)
        {
            /*Node itself*/
            B3D_Node b3D_Node = new B3D_Node(spatial.getName(), null);
            spatial.setUserData("ID", b3D_Node.getID().toString());
            b3D_Spatial = b3D_Node;
            CurrentData.getEditorWindow().getB3DApplication().getElementList().putByObject(
                    spatial, b3D_Node);
            /*Register Geometrys*/
            for (Spatial geo : ((Node) spatial).getChildren())
            {
                register(geo, (Node) spatial);
            }
            new NodeModel((Node) spatial);
        }
        if (parent == null)
        {
            //System.out.println(CurrentData.getEditorWindow().getB3DApplication().getSelectedNode().getName());
            if (CurrentData.getEditorWindow().getB3DApplication().getSelectedNode().equals(this) && spatial.getUserData("parentID") == null)
            {
                super.attachChild(spatial);
            } else if (spatial.getUserData("parentID") != null)
            {
                ((B3D_Spatial) CurrentData.getEditorWindow().getB3DApplication().getElementList().getElement(spatial)).setParentID(UUID.fromString(spatial.getUserData("parentID").toString()));
                parent = (Node) CurrentData.getEditorWindow().getB3DApplication().getElementList().getObject(UUID.fromString(spatial.getUserData("parentID").toString()));
                parent.attachChild(spatial);
            } else
            {
                B3D_Spatial parentElement = null;
                if ((B3D_Spatial) CurrentData.getEditorWindow().getB3DApplication().getSelectedElement() != null)
                {
                    parentElement = (B3D_Spatial) CurrentData.getEditorWindow().getB3DApplication().getSelectedElement();
                } else
                {
                    parentElement = (B3D_Spatial) CurrentData.getEditorWindow().getB3DApplication().getElementList().getElement(
                            CurrentData.getEditorWindow().getB3DApplication().getNewParent());
                }
                ((B3D_Spatial) CurrentData.getEditorWindow().getB3DApplication().getElementList().getElement(spatial)).setParentID(
                        (parentElement.getID()));
                spatial.setUserData("parentID", ((B3D_Spatial) CurrentData.getEditorWindow().getB3DApplication().getElementList().getElement(spatial)).getParentID().toString());
                //CurrentData.getEditorWindow().getB3DApplication().getSelectedNode().attachChild(spatial);
                parent = (Node) CurrentData.getEditorWindow().getB3DApplication().getElementList().getObject(UUID.fromString(spatial.getUserData("parentID").toString()));
                parent.attachChild(spatial);
            }
        } else
        {
            System.out.println("Adding: " + spatial.getName() + " to " + parent.getName());
            ((B3D_Spatial) CurrentData.getEditorWindow().getB3DApplication().getElementList().getElement(spatial)).setParentID(
                    CurrentData.getEditorWindow().getB3DApplication().getElementList().getElement(parent).getID());
            spatial.setUserData("parentID", CurrentData.getEditorWindow().getB3DApplication().getElementList().getElement(parent).getID().toString());
            parent.attachChild(spatial);
        }
        CurrentData.getEditorWindow().getTree().sync();
        /*if (parentID != null)
         {
         Node node = (Node) CurrentData.getEditorWindow().getB3DApplication().getElementList().getObject(parentID);// #yolo
         node.attachChild(spatial);
         } else
         {
         super.attachChild(spatial);
         }*/
        /*if (!child)
         {
         if (CurrentData.getEditorWindow().getB3DApplication().getSelectedObject() instanceof Node)
         {
         ((Node) CurrentData.getEditorWindow().getB3DApplication().getSelectedObject()).attachChild(spatial);
         ((B3D_Spatial) CurrentData.getEditorWindow().getB3DApplication().getElementList().getElement(spatial)).setParentID(
         ((B3D_Spatial) CurrentData.getEditorWindow().getB3DApplication().getSelectedElement()).getID());
         } else
         {
         super.attachChild(spatial);
         }
         CurrentData.getEditorWindow().getB3DApplication().setSyncTree(true);
         }*/
        b3D_Spatial.setRotation(spatial.getLocalRotation());
        b3D_Spatial.setScale(spatial.getLocalScale());
        b3D_Spatial.setTranslation(spatial.getLocalTranslation());
    }
}